<?php

namespace App\Tools\Hldy;

use App\Tools\Hldy\Base as ToolBase;

class Fish extends ToolBase
{
    /**
     * getConfigXXX为配置项方法
     */

    /**
     * 获取所有鱼对应的倍率值
     * @param $gold
     */
    protected static function getConfigFishTimesInfo() {
        return config('hldy.fish_times_info');
    }

    /**
     * 所有鱼命中概率
     * @return array
     */
    protected static function getConfigHitRate() {
        return config('hldy.fish_hit_rate');
    }

    /**
     * 一杆钓N条鱼的条数概率
     */
    protected static function getConfigHitNumRate() {
        return config('hldy.hit_num_rate');
    }

    /**
     * 给定金币钓到条数提升倍率
     */
    protected static function getConfigGoldAddHitRate() {
        return config('hldy.gold_add_hit_rate');
    }

    /**
     * 获取鱼的倍率
     * @param $fishId
     */
    public static function getFishTimes($fishId) {
        $fishTimesInfo = self::getConfigFishTimesInfo();

        return $fishTimesInfo[$fishId]['times'];
    }

    /**
     * 检测是否合法下杆金币
     * @param $gold
     *
     * @return bool
     */
    public static function checkGoldIsValid($gold) {
        $goldList = config('hldy.gold_list');

        return in_array((int)$gold, $goldList, true);
    }

    /**
     * 给定金币，钓到几条鱼
     * @param $gold
     */
    public static function getHitNum($gold) {
        $addRateList = self::getConfigGoldAddHitRate();
        $hitNumRateList = self::getConfigHitNumRate();

        $addRate = $addRateList[$gold];
        if($addRate > 0) {
            unset($hitNumRateList[0]);  //移除不中

            $sumRate = 0;
            foreach ($hitNumRateList as $key => $rateItem) {
                $hitNumRateList[$key]['rate'] += $addRate;
                $sumRate += $hitNumRateList[$key]['rate'];
            }

            $hitNumRateList[0] = [
                'id'   => 0,
                'rate' => max(0, 100-$sumRate),
            ];
        }

        $hitItem = self::getRandHit($hitNumRateList);

        return $hitItem['id'];
    }

    /**
     * 钓到，取鱼
     * @param $fishNum
     * @param $goldNum
     */
    public static function takeFish($fishNum, $goldNum) {
        $fishHitRate = self::getConfigHitRate();
        $takeInfo = [];
        $totalGold = 0;
        for($i = 0; $i < $fishNum; $i++) {
            $hitFish = self::getRandHit($fishHitRate);
            $getGold = self::getFishTimes($hitFish['id']) * $goldNum;
            $takeInfo[] = [
                'id'    => $hitFish['id'],
                'name'  => $hitFish['name'],
                'times' => self::getFishTimes($hitFish['id']),
                'gold'  => $getGold,
                'num'   => 1,
            ];
            $totalGold += $getGold;
            /*
            if(!isset($takeInfo[$hitFish['id']])) {
                $takeInfo[$hitFish['id']] = [
                    'id'    => $hitFish['id'],
                    'name'  => $hitFish['name'],
                    'times' => self::getFishTimes($hitFish['id']),
                    'gold'  => 0,
                    'num'   => 0,
                ];  //以鱼的id汇总
            }


            $takeInfo[$hitFish['id']]['num']++;
            $takeInfo[$hitFish['id']]['gold'] += $getGold;
            $totalGold += $getGold;
            */
        }
        $returnData = [
            'fishList'   => array_values($takeInfo),
            'totalGold'  => $totalGold,
        ];

        return $returnData;
    }

    /**
     * 获取随机命中项
     * @param  array $rateList  每条记录带有概率rate字段的二维数组
     * @return array
     */
    public static function getRandHit($rateList) {
        $itemList = array();
        foreach($rateList as $index => $item) {
            $itemNum = $item['rate'] * 1000;    //千倍化数据
            //以下标为值，得到倍率对应的份数，组合成一个大数组，随机抽出来数组的一个位置后，可基于该位置获得对应的下标，最终获得命中项
            $itemList = array_merge($itemList, array_fill(0, $itemNum, $index)); //无覆盖追加
        }

        $shuffleTimes = rand(3, 5);
        for($i = 0; $i < $shuffleTimes; $i++) {
            shuffle($itemList);
        }

        //随机抽取大数组itemList中的一个位置
        $hitRandIndex = rand(0, count($itemList) - 1);

        //通过位置得到对应下标
        $rangeRateMapIndex = $itemList[$hitRandIndex];

        //通过下标得到命中项
        return $rateList[$rangeRateMapIndex];
    }
}
